<?php
include_once('data.php');
include_once(Utils::getPath(array('model', 'comment.php')));
include_once(Utils::getPath(array('model', 'commentType.php')));

class CommentRepository {

    private $lastFilter;

    //The types of comments are constants.
    const TYPE_ID_CHALLENGE = 1;
    const TYPE_ID_SOLUTION = 2;

    public function getById($commentId) {
        if (is_numeric($commentId)) {
            $row = Database::select('*', 'comments', array(array('Id = ?', $commentId, PDO::PARAM_INT)));

            if ($row->rowCount() == 1) {
                $comment = $row->fetchObject('Comment');
                return $comment;
            }
        }
        return null;
    }

    public function getAll($order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        return $this->find(null, $order, $desc, $pageIndex, $pageCount);
    }

    public function getByIdSolution($id, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("IdSolution = ?", $id, PDO::PARAM_INT);
        $filterParams[] = array("AND IdType = ?", 2, PDO::PARAM_INT);
        $this->lastFilter = $filterParams;

        return $this->find($filterParams, $order, $desc, $pageIndex, $pageCount);
    }

    public function getByIdChallenge($id, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("IdChallenge = ?", $id, PDO::PARAM_INT);
        $filterParams[] = array("AND IdType = ?", 1, PDO::PARAM_INT);
        $this->lastFilter = $filterParams;

        return $this->find($filterParams, $order, $desc, $pageIndex, $pageCount);
    }

    public function findByType($typeId, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("IdType = ?", $typeId, PDO::PARAM_INT);

        return $this->find($filterParams, $order, $desc, $pageIndex, $pageCount);
    }

    public function findByAuthor($authorId, $typeId = null, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $filterParams = array();
        $filterParams[] = array("IdAuthor = ?", $authorId, PDO::PARAM_INT);

        if ($typeId != null) {
            $filterParams[] = array("AND IdType = ?", $typeId, PDO::PARAM_INT);
        }

        return $this->find($filterParams, $order, $desc, $pageIndex, $pageCount);
    }

    public function findByChallengeAuthor($challengeAuthor, $filterParams, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $strfilter = '';
        if (count($filterParams) > 0)
            $strfilter = ' AND ';
        $filterParams[] = array($strfilter . "challenges.IdAuthor = ?", $challengeAuthor, PDO::PARAM_INT);

        $rows = Database::select('comments.Id AS Id, comments.IdAuthor AS IdAuthor, comments.IdType AS IdType, comments.IdChallenge AS IdChallenge, comments.IdSolution AS IdSolution, comments.Text AS Text, comments.Date AS Date', 'comments JOIN challenges ON comments.IdChallenge = challenges.Id', $filterParams, $order, $desc, $pageIndex * $pageCount, $pageCount);

        if ($rows->rowCount() > 0) {
            $comments = $rows->fetchAll(PDO::FETCH_CLASS, "Comment");
            return $comments;
        }
        return null;
    }

    public function findBySolutionAuthor($solutionAuthor, $filterParams, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $strfilter = '';
        if (count($filterParams) > 0)
            $strfilter = ' AND ';
        $filterParams[] = array($strfilter . "solutions.IdAuthor = ?", $solutionAuthor, PDO::PARAM_INT);

        $rows = Database::select('comments.Id AS Id, comments.IdAuthor AS IdAuthor, comments.IdType AS IdType, comments.IdChallenge AS IdChallenge, comments.IdSolution AS IdSolution, comments.Text AS Text, comments.Date AS Date', 'comments JOIN solutions ON comments.IdSolution = solutions.Id', $filterParams, $order, $desc, $pageIndex * $pageCount, $pageCount);

        if ($rows->rowCount() > 0) {
            $comments = $rows->fetchAll(PDO::FETCH_CLASS, "Comment");
            return $comments;
        }
        return null;
    }    

    public function find($filterParams, $order = null, $desc = null, $pageIndex = 0, $pageCount = 10) {
        $rows = Database::select('*', 'comments', $filterParams, $order, $desc, $pageIndex * $pageCount, $pageCount);
        $this->lastFilter = $filterParams;
        if ($rows->rowCount() > 0) {
            $comments = $rows->fetchAll(PDO::FETCH_CLASS, "Comment");
            return $comments;
        }
        return null;
    }

    private function getLast() {
        $row = Database::select('*', 'comments', null, 'Id', true, 0, 1);

        if ($row->rowCount() == 1) {
            $comment = $row->fetchObject('Comment');
            return $comment;
        }
        return null;
    }

    public function persist($comment) {
        $values = array();

        $values[] = array('Id', $comment->getId(), PDO::PARAM_INT);
        $values[] = array('IdAuthor', $comment->getIdAuthor(), PDO::PARAM_INT);
        $values[] = array('IdType', $comment->getIdType(), PDO::PARAM_INT);
        if ($comment->getIdType() == self::TYPE_ID_CHALLENGE) {
            $values[] = array('IdChallenge', $comment->getIdChallenge(), PDO::PARAM_INT);
            $values[] = array('IdSolution', null, PDO::PARAM_NULL);
        } else if ($comment->getIdType() == self::TYPE_ID_SOLUTION) {
            $values[] = array('IdChallenge', null, PDO::PARAM_NULL);
            $values[] = array('IdSolution', $comment->getIdSolution(), PDO::PARAM_INT);
        }
        else
            return null;
        $values[] = array('Text', $comment->getText(), PDO::PARAM_STR);
        $values[] = array('Date', $comment->getDate(), PDO::PARAM_STR);

        if (!$comment->IsPersited()) {
            $res = Database::insert('comments', $values);
            if ($res)
                return $this->getLast();
        }
        else {
            $res = DataBase::update('comments', $values, array(array('Id = ?', $comment->getId(), PDO::PARAM_INT)));
            if ($res)
                return $this->getById($comment->getId());
        }

        return null;
    }

    public function remove($comment) {
        $res = Database::remove('comments', array(array('Id = ?', $comment->getId(), PDO::PARAM_INT)));
        return $res;
    }

    public function countLast() {
        $rows = Database::select('Count(*)', 'comments', $this->lastFilter, null, null, null, null);

        if ($rows->rowCount() == 1) {
            $row = $rows->fetch(PDO::FETCH_NUM);
            return $row[0];
        }
        return null;
    }

    public function getTypeById($typeId) {
        if (is_numeric($typeId)) {
            $row = Database::select('*', 'comment_types', array(array('Id = ?', $typeId, PDO::PARAM_INT)));

            if ($row->rowCount() == 1) {
                $type = $row->fetchObject('CommentType');
                return $type;
            }
        }
        return null;
    }

}

?>